package net.WMisiedjan.BukkitToDate.Launcher;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.logging.Logger;
//import org.yaml.*;
import org.bukkit.util.config.*;

public class BTDClass {

	public Logger log = Logger.getLogger("Minecraft");
	public Configuration Config = null;

	public int btd_restarttimer = 5;
	public String[] versionargs = null;
	public int btd_currentbuild = 0;
	public int btd_previousbuild = 1;
	public int btd_jenkisbuild = 0;
	public int btd_jenkisrecommendbuild = 0;
	public int btd_switchto = 0;
	public boolean btd_autoupdate = false;
	public boolean btd_monitor = true;
	public boolean btd_preventexits = false; // Automaticly restarts the server
												// on crash.
	public int btd_monitorinterval = 20;
	public boolean btd_recommendbuilds = false;
	public Thread MonitorThread = null;

	public BTDClass() {

	}

	public boolean checkConfig() {
		boolean returnbool = true;
		File directory = new File("plugins\\BukkitToDate\\");
		if (!directory.exists()) {
			directory.mkdir();
			directory = new File("bukkit_build\\");
			directory.mkdir();
			log.info("BukkitToDate: Created plugin folders...");
		}

		File checkFile = new File("plugins\\BukkitToDate\\config.yml");

		if (!checkFile.exists()) {
			try {
				checkFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
				returnbool = false;
			}

			log.info("Created Settings file! It's recommand to change it to your wishes.");

			checkFile = new File("plugins\\BukkitToDate\\config.yml");

			Config = new Configuration(checkFile);

			if (!this.SaveConfig()) {
				log.warning("Plugin UNLOADED" + ", Configuration saving error!");
			}
		}

		if (checkFile.exists()) {
			Config = new org.bukkit.util.config.Configuration(checkFile);
			Config.load();

			btd_previousbuild = (Integer) Config.getProperty("previousbuild");
			btd_restarttimer = (Integer) Config.getProperty("restarttimer");
			btd_autoupdate = (Boolean) Config.getProperty("auto-update");
			btd_monitor = (Boolean) Config.getProperty("enable-monitor");
			btd_monitorinterval = (Integer) Config
					.getProperty("monitor-interval");
			btd_switchto = (Integer) Config.getProperty("switchto");
			btd_preventexits = (Boolean) Config.getProperty("preventexits");
			btd_recommendbuilds = (Boolean) Config.getProperty("recommendbuilds");
		}

		return returnbool;
	}

	public boolean SaveConfig() {
		Config.setProperty("restarttimer", btd_restarttimer);
		Config.setProperty("previousbuild", btd_previousbuild);
		Config.setProperty("auto-update", btd_autoupdate);
		Config.setProperty("enable-monitor", btd_monitor);
		Config.setProperty("monitor-interval", btd_monitorinterval);
		Config.setProperty("switchto", btd_switchto);
		Config.setProperty("preventexits", btd_preventexits);
		Config.setProperty("recommendbuilds", btd_recommendbuilds);

		return Config.save();
	}

	public boolean isCurrent() {
		if (btd_recommendbuilds) {
			this.btd_jenkisrecommendbuild = getJenkisRecommendVersion();

			if (this.btd_jenkisrecommendbuild == this.btd_currentbuild) {
				System.out.println("Server is Up-To-Date at Recommend build #"
						+ this.btd_jenkisrecommendbuild);
				return true;
			}
			System.out.println("Server is Outdated! Your build: #"
					+ this.btd_currentbuild + ", Jenkis Recommend build: #"
					+ this.btd_jenkisrecommendbuild);
			return false;
		} else {
			this.btd_jenkisbuild = getJenkisVersion();

			if (this.btd_jenkisbuild == this.btd_currentbuild) {
				System.out.println("Server is Up-To-Date at Dev build #"
						+ this.btd_jenkisbuild);
				return true;
			}
			System.out.println("Server is Outdated! Your build: #"
					+ this.btd_currentbuild + ", Jenkis Dev build: #"
					+ this.btd_jenkisbuild);
			return false;
		}
	}

	public int getJenkisRecommendVersion() {
		URL buids = null;
		try {
			buids = new URL(
					"http://ci.bukkit.org/job/recommended-CraftBukkit/lastSuccessfulBuild/");
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		URLConnection buildsc = null;
		try {
			buildsc = buids.openConnection();
		} catch (IOException e) {
			e.printStackTrace();
		}
		HttpURLConnection connection = null;
		connection = (HttpURLConnection) buildsc;
		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(
					connection.getInputStream()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String line = null;
		try {
			while ((line = in.readLine()) != null) {
				if ((line.contains("<titel>"))) {
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String build = line.replaceAll("    <title>recommended-CraftBukkit #",
				"");
		build = build.substring(0, 3);
		System.out.println("DEBUG:" + build);
		connection.disconnect();

		if (build != null)
			this.btd_jenkisrecommendbuild = Integer.parseInt(build);

		return this.btd_jenkisrecommendbuild;
	}

	public int getJenkisVersion() {
		URL buids = null;
		try {
			buids = new URL(
					"http://ci.bukkit.org/job/dev-CraftBukkit/lastSuccessfulBuild/");
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		URLConnection buildsc = null;
		try {
			buildsc = buids.openConnection();
		} catch (IOException e) {
			e.printStackTrace();
		}
		HttpURLConnection connection = null;
		connection = (HttpURLConnection) buildsc;
		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(
					connection.getInputStream()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String line = null;
		try {
			while ((line = in.readLine()) != null) {
				if ((line.contains("<titel>"))) {
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String build = line.replaceAll("    <title>dev-CraftBukkit #", "");
		build = build.substring(0, 3);
		System.out.println("DEBUG:" + build);
		connection.disconnect();

		if (build != null)
			this.btd_jenkisbuild = Integer.parseInt(build);

		return this.btd_jenkisbuild;
	}

	public boolean SwitchTo(int btd_switchto2, boolean recommended) {
		return MoveBuild(btd_switchto2, recommended);
	}

	public boolean MoveBuild(int buildid, boolean recommended) {
		boolean returnbool = true;
		File file = null;
		
		if(recommended)
		{
			file = new File("bukkit_build/craftbukkit_REC_" + buildid
				+ ".jar");
		}
		else
		{
			file = new File("bukkit_build/craftbukkit_DEV_" + buildid
					+ ".jar");
		}

		if (file.exists()) {
			File orginal = new File("craftbukkit.jar");
			boolean issucces = true;
			if (orginal.exists()) {
				if (!orginal.delete()) {
					System.out
							.println("Error deleting orginal craftbukkit.jar!");
					System.out.println("Next try in 5 seconds..");
					try {
						Thread.sleep(5000L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					if (!orginal.delete()) {
						System.out
								.println("Error deleting orginal craftbukkit.jar!");

						issucces = false;
					} else {
						issucces = true;
					}

				} else {
					issucces = true;
				}
			}

			if (issucces) {
				File dir = new File(".");
				try {
					System.out.println(dir.getCanonicalPath());
				} catch (IOException e) {
					e.printStackTrace();
				}

				boolean success = true;
				try {
					copyFile(file, orginal);
				} catch (IOException e) {
					e.printStackTrace();
					success = false;
				}

				if (!success) {
					System.out.println("Cannot copy/rename build #" + buildid
							+ " to craftbukkit.jar!");
					returnbool = false;
				} else {
					System.out.println("Succesly updated to build: " + buildid);
					this.btd_previousbuild = this.btd_currentbuild;
					this.SaveConfig();
					returnbool = true;
				}
			}
		} else {
			returnbool = false;
			System.out.println("This build (" + buildid + ") doesn't exists..");
		}

		return returnbool;
	}

	public void copyFile(File in, File out) throws IOException {
		FileInputStream fis = new FileInputStream(in);

		FileOutputStream fos = new FileOutputStream(out);

		FileChannel fci = fis.getChannel();

		FileChannel fco = fos.getChannel();

		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while (true) {
			int read = fci.read(buffer);

			if (read == -1) {
				break;
			}
			buffer.flip();

			fco.write(buffer);

			buffer.clear();
		}
	}

	public Boolean DownloadJenkisBuild(int buildid, boolean recommended)
			throws IOException {
		try {
			File location = null;
			URL url = null;
			if (recommended) {
				location = new File("bukkit_build/craftbukkit_REC_" + buildid
						+ ".jar");
				url = new URL(
						"http://ci.bukkit.org/job/recommended-CraftBukkit/"+buildid+"/artifact/output/craftbukkit.jar");
			} else {
				location = new File("bukkit_build/craftbukkit_DEV_" + buildid
						+ ".jar");
				url = new URL(
						"http://ci.bukkit.org/job/dev-CraftBukkit/"+buildid+"/artifact/target/craftbukkit-0.0.1-SNAPSHOT.jar");
			}

			//
			BufferedInputStream in = new BufferedInputStream(url.openStream());
			FileOutputStream fos = new FileOutputStream(location);
			BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
			byte[] data = new byte[1024];
			int count;
			while ((count = in.read(data, 0, 1024)) != -1) {
				bout.write(data, 0, count);
			}
			bout.close();
			in.close();
			return true;
		} catch (Exception e) {
			log.info(e.getMessage());
			return false;
		}
	}

}
